<?php

namespace app\admin\controller;

use think\Controller;
use think\Db;
use think\Cache;
use think\Request;
use think\Session;

class Common extends Controller
{
    public function _initialize()
    {
        /**
         * 检查是否登录
         */
        if (!$this->check_login()) {
            $this->redirect(url('/admin/login/login'));
        }
        /**
         * 获取导航
         */
        $menu = $this->getMenu();
        $this->assign('menu', $menu);
        
        /**
         * 获取菜单树形结构
         * */
        $this->getMenuTree();
        
        /**
         * 获取配置分组
         * */
        $this->getConfigGroup();
        
        /**
         * 设置配置
         * */
        $this->setSystemConfig();
        
        /**
         * 检查权限
         */
        $this->checkUrlAuth();
        
        // 记录操作日志
        $this->operationLog();
    }
    
    /**
     * 获取导航数据
     *
     * @return mixed
     */
    public function getMenu()
    {
        $menu = cache('admin_menu' . session('id'));
        
        if (!$menu) {
            //权限控制菜单显示
            $uid = session('id');
            if ($uid > 1) {
                $user_rules_arr = $this->getUserAuthMenuId($uid);
                if ($user_rules_arr) {
                    $auth_where['id'] = ['IN', $user_rules_arr];
                } else {
                    Session::clear();
                    Cache::clear();
                    $this->error('该账号无权限', url('/admin/login/login'));
                }
            } elseif (empty($uid)) {
                $this->error('登录身份已过期，请重新登录', url('/admin/login/login'));
            }
            
            $menu = Db::name('menu')->field('id,icon,name,url')->where(['pid' => 0, 'status' => 1, 'is_show' => 1])->where($auth_where)->order('sort asc')->select();
            if ($menu) {
                foreach ($menu as &$v) {
                    $leftMenu = Db::name('menu')->field('id,icon,name,url')->where(['pid' => $v['id'], 'status' => 1, 'is_show' => 1])->where($auth_where)->order('sort asc')->select();
                    if ($leftMenu) {
                        foreach ($leftMenu as $key => &$val) {
                            if ($key == 0) $v['url'] = $val['url'];
                            $sonMenu = Db::name('menu')->field('id,icon,name,url')->where(['pid' => $val['id'], 'status' => 1, 'is_show' => 1])->where($auth_where)->order('sort asc')->select();
                            $val['sonMenu'] = $sonMenu;
                            if (empty($val['url']) && count($sonMenu) > 0) $val['url'] = $sonMenu[0]['url'];
                        }
                    }
                    $v['leftMenu'] = $leftMenu;
                }
            }
            cache('admin_menu' . session('id'), $menu);
        }
        
        return $menu;
    }
    
    /**
     * 后台菜单树形结构
     * */
    function getMenuTree()
    {
        $menu = cache('menu_tree' . session('id'));
        if (!$menu) {
            $menu = Db::name('menu')->field('id,name')->where(['pid' => 0, 'status' => 1])->order('sort asc')->select();
            if ($menu) {
                foreach ($menu as &$v) {
                    $groupMenu = Db::name('menu')->field('id,name')->where(['pid' => $v['id'], 'status' => 1])->order('sort asc')->select();
                    if ($groupMenu) {
                        foreach ($groupMenu as &$val) {
                            $list_menu = Db::name('menu')->field('id,name')->where(['pid' => $val['id'], 'status' => 1])->order('sort asc')->select();
                            if ($list_menu) {
                                foreach ($list_menu as &$value) {
                                    $do_menu = Db::name('menu')->field('id,name')->where(['pid' => $value['id'], 'status' => 1])->order('sort asc')->select();
                                    $value['do_menu'] = $do_menu;
                                }
                            }
                            $val['list_menu'] = $list_menu;
                        }
                    }
                    $v['group_menu'] = $groupMenu;
                }
            }
            
            cache('menu_tree' . session('id'), $menu);
        }
        
        return $menu;
    }
    
    /**
     * 获取配置分组
     * */
    public function getConfigGroup()
    {
        $configGroup = cache('configGroup');
        if (empty($configGroup)) {
            $configGroup = Db::name('config_group')->field('id,name,sort')->order('sort asc')->select();
            cache('configGroup', $configGroup);
        }
        
        return $configGroup;
    }
    
    /**
     * 设置配置
     * */
    public function setSystemConfig()
    {
        $config = cache('systemConfig');
        if (!$config) {
            $config = Db::name('config')->field('id,name,title,value,type,group_id')->order('sort asc')->select();
            if ($config) {
                foreach ($config as &$v) {
                    $v['output_value'] = $v['value'];
                    if ($v['type'] == 4) $v['output_value'] = preg_split("/(,|，|;|[\r\n])/", $v['output_value']);
                }
            }
            cache('systemConfig', $config);
        }
    }
    
    /**
     * 检查是否登录
     *
     * @return bool
     */
    public function check_login()
    {
        if (!session('id', '') || !session('account', '')) {
            return false;
        }
        
        return true;
    }
    
    /**
     * 获取当前登录用户权限菜单id
     * */
    public function getUserAuthMenuId($uid)
    {
        $rules_list = Db::name('auth_group_access')->alias('a')->field('g.rules')->join('auth_group g', 'a.group_id = g.id')->where(['a.uid' => $uid, 'g.status' => 1])->select();
        if ($rules_list) {
            $new_rules = '';
            foreach ($rules_list as &$v) {
                if ($new_rules == '') {
                    $new_rules = $v['rules'];
                } else {
                    $new_rules = $new_rules . ',' . $v['rules'];
                }
            }
            //数组去重
            $new_rules_arr = array_unique(explode(',', $new_rules));
            
            return $new_rules_arr;
        } else {
            return [];
        }
    }
    
    /**
     * 检查某个url是否有权限访问
     * */
    public function checkUrlAuth()
    {
        $uid = session('id');
        if ($uid > 1) {
            $status = Db::name('user')->where(['id' => $uid])->value('status');
            if($status == 2){
                Session::clear();
                Cache::clear();
                $this->error('您的账号已被禁用', url('/admin/login/login'));
            }
            
            $user_rules_arr = $this->getUserAuthMenuId($uid);
            if (empty($user_rules_arr)) {
                Session::clear();
                Cache::clear();
                $this->error('您无权限访问', url('/admin/login/login'));
            }
            $auth_where['id'] = ['IN', $user_rules_arr];
            
            $menu_list = Db::name('menu')->field('url')->where($auth_where)->select();
            if ($menu_list) {
                $visit_url = strtoupper(str_replace('.html', '', getRequestUri()));
                $auth_urls = strtoupper(implode(',', array_column($menu_list, 'url')));
                if (!(strpos($auth_urls, $visit_url) !== false)) $this->error('您无权限访问');
            }
        } elseif (empty($uid)) {
            $this->redirect(url('/admin/login/login'));
        }
    }
    
    /**
     * 记录操作日志
     * */
    public function operationLog()
    {
        $server = $_SERVER;
        $path_info = $server['PATH_INFO'];
        $redirect_status = $server['REDIRECT_STATUS'];
        $time = time();
        
        $user_id = session('id');
        $username = Db::name('user')->where(['id' => $user_id])->value('username');
        $desc = Db::name('menu')->where(['url' => str_replace('.html', '', $path_info)])->order('level desc')->value('name');
        
        if ($redirect_status == 200 && $user_id && $username && $desc) {
            $data = [
                'user_id' => $user_id,
                'username' => $username,
                'url' => $path_info,
                'desc' => $desc,
                'create_time' => $time
            ];
            
            Db::name('operation_log')->insert($data);
        }
    }
}